﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace KPIS.GERP.GHRMS.MODEL
{
    public class TableInfo
    {
        public enum Field
        {
            PrimaryKey,
            PrimaryKeyClass,
            RecordStatusField,
            RecordStatusFieldClass,
            CreateBy,
            CreateByClass,
            CreateWhen,
            CreateWhenClass,
            UpdateBy,
            UpdateByClass,
            UpdateWhen,
            UpdateWhenClass,
            TableName,
            TableNameClass
        }

        public enum From
        {
            Class,
            Attribute
        }

        public string PrimaryKey
        {
            get { return GetSequenceFieldName(Field.PrimaryKey, From.Attribute); }
        }

        public string PrimaryKeyClass
        {
            get { return GetSequenceFieldName(Field.PrimaryKey); }
        }

        public string RecordStatusField
        {
            get { return GetSequenceFieldName(Field.RecordStatusField, From.Attribute); }
        }

        public string RecordStatusFieldClass
        {
            get { return GetSequenceFieldName(Field.RecordStatusFieldClass); }
        }

        public string CreateBy
        {
            get { return GetSequenceFieldName(Field.CreateBy, From.Attribute); }
        }

        public string CreateByClass
        {
            get { return GetSequenceFieldName(Field.CreateBy); }
        }

        public string CreateWhen
        {
            get { return GetSequenceFieldName(Field.CreateWhen, From.Attribute); }
        }

        public string CreateWhenClass
        {
            get { return GetSequenceFieldName(Field.CreateWhen); }
        }

        public string UpdateBy
        {
            get { return GetSequenceFieldName(Field.UpdateBy, From.Attribute); }
        }

        public string UpdateByClass
        {
            get { return GetSequenceFieldName(Field.UpdateBy); }
        }

        public string UpdateWhen
        {
            get { return GetSequenceFieldName(Field.UpdateWhen, From.Attribute); }
        }

        public string UpdateWhenClass
        {
            get { return GetSequenceFieldName(Field.UpdateWhen); }
        }

        public string TableName
        {
            get
            {
                var dnAttribute = this.GetType().GetCustomAttributes(
                    typeof (TableNameAttribute), true
                                      ).FirstOrDefault() as TableNameAttribute;
                if (dnAttribute != null)
                {
                    return dnAttribute.TableName;
                }
                return null;
            }
        }

        public string GetSequenceFieldName(Field specialFieldType, From from = From.Class)
        {
            var propertyInfos = this.GetType().GetProperties();

            foreach (PropertyInfo pInfo in propertyInfos)
            {
                if (Attribute.IsDefined(pInfo, typeof (FieldAttribute)))
                {
                    if (from == From.Class)
                    {
                        var fieldAttribute =
                            (FieldAttribute) Attribute.GetCustomAttribute(pInfo, typeof (FieldAttribute));

                        if (specialFieldType == Field.PrimaryKey && fieldAttribute.IsPrimaryKey)
                            return pInfo.Name;

                        if (specialFieldType == Field.CreateBy && fieldAttribute.IsCreateBy)
                            return pInfo.Name;

                        if (specialFieldType == Field.CreateWhen && fieldAttribute.IsCreateWhen)
                            return pInfo.Name;

                        if (specialFieldType == Field.UpdateBy && fieldAttribute.IsUpdateBy)
                            return pInfo.Name;

                        if (specialFieldType == Field.UpdateWhen && fieldAttribute.IsUpdateWhen)
                            return pInfo.Name;

                        if (specialFieldType == Field.RecordStatusField && fieldAttribute.IsRecordStatus)
                            return pInfo.Name;
                    }
                    else
                    {

                        var fieldAttribute =
                            (FieldAttribute) Attribute.GetCustomAttribute(pInfo, typeof (FieldAttribute));

                        if (specialFieldType == Field.PrimaryKey && fieldAttribute.IsPrimaryKey)
                            return fieldAttribute.FieldName;

                        if (specialFieldType == Field.CreateBy && fieldAttribute.IsCreateBy)
                            return fieldAttribute.FieldName;

                        if (specialFieldType == Field.CreateWhen && fieldAttribute.IsCreateWhen)
                            return fieldAttribute.FieldName;

                        if (specialFieldType == Field.UpdateBy && fieldAttribute.IsUpdateBy)
                            return fieldAttribute.FieldName;

                        if (specialFieldType == Field.UpdateWhen && fieldAttribute.IsUpdateWhen)
                            return fieldAttribute.FieldName;

                        if (specialFieldType == Field.RecordStatusField && fieldAttribute.IsRecordStatus)
                            return fieldAttribute.FieldName;
                    }
                }
            }

            return null;
        }
    }
}